-- $Id: $
-- File name:   FRAME_SYNC.vhd
-- Created:     3/22/2011
-- Author:      Brandon Blaine Gardner
-- Lab Section: 337-06
-- Version:     1.0  Initial Design Entry
-- Description: Frame synchronizer and tag specifier.  Runs SYNC signal.  
--              Expect 48 MHz CLK.


LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_arith.ALL;
USE IEEE.std_logic_unsigned.ALL;

entity FRAME_SYNC is
  port(
    CLK  : in  std_logic;
    RST  : in  std_logic;
    EN   : in  std_logic; -- enable
    SYNC : out std_logic
  );
end FRAME_SYNC;

architecture tag_arch of FRAME_SYNC is
  
  type state_type is ( INIT, FrameSync, Command, P1, D1, P2, D2 );
  signal state, nextstate : state_type;
  
  attribute ENUM_ENCODING: STRING;
  attribute ENUM_ENCODING of state_type:type is "000 001 011 010 110 111 101";
  
  signal sync_int, sync_int_f : std_logic;
  signal bitcount, nextbitcount : std_logic_vector(2 downto 0); -- 3 bits
  signal bytecount, nextbytecount : std_logic_vector(6 downto 0); -- 7 bits
  
begin
  
  state_register : process( CLK, RST )
  begin
    if( RST = '0' )
    then
      state <= INIT;
      bitcount <= "000";
      bytecount <= "0000000";
      sync_int_f <= '0';
    elsif( rising_edge(CLK) ) -- NOT double pumped
    then
      state <= nextstate;
      bitcount <= nextbitcount;
      bytecount <= nextbytecount;
      sync_int_f <= sync_int;
    end if;
  end process state_register;
    
  nextstate_logic : process( state,
  			bitcount, bytecount, 
  			nextbitcount, nextbytecount, EN )
  begin
    
    nextstate <= state;
    nextbitcount <= bitcount;
    nextbytecount <= bytecount;
    sync_int <= '0';
    
    case state is
      
    when INIT =>
      if( EN = '1' )
      then
        nextstate <= FrameSync;
      end if;
      
    when FrameSync =>
      sync_int <= '1';
      if( EN = '0' )
      then
        nextstate <= INIT;
      elsif( bitcount = "111" )
      then
        nextbitcount <= "000";
        nextbytecount <= bytecount + 1;
        nextstate <= Command;
      else
        nextbitcount <= bitcount + 1;
      end if;
      
    when Command =>
      if( EN = '0' )
      then
        nextstate <= INIT; 
      elsif( bitcount = "111" )
      then
        nextbitcount <= "000";
        nextbytecount <= bytecount + 1;
        if( bytecount = "0000100" )
        then
          nextstate <= P1;
        end if;
      else
				nextbitcount <= bitcount + 1;
      end if;
      
    when P1 =>
      if( bitcount="000" or bitcount="001" or bitcount="010" or bitcount="111" )
      then
      	sync_int <= '1';
      end if;
      if( EN = '0' )
      then
				nextstate <= INIT;
      elsif( bitcount = "111" )
      then
				nextbitcount <= "000";
				nextbytecount <= bytecount + 1;
				nextstate <= D1;
      else
				nextbitcount <= bitcount + 1;
      end if;
      
    when D1 =>
      if( EN = '0' )
      then
				nextstate <= INIT;
      elsif( bitcount = "111" )
      then
				nextbitcount <= "000";
				nextbytecount <= bytecount + 1;
				if( bytecount = "0100100" )
				then
				  nextstate <= P2;
				end if;
			else
				nextbitcount <= bitcount + 1;
   		end if;
      
    when P2 =>
      if( bitcount="000" or bitcount="001" or bitcount="010" or bitcount="110" )
      then
      	sync_int <= '1';
      end if;
      if( EN = '0' )
      then
				nextstate <= INIT;
      elsif( bitcount = "111" )
      then
				nextbitcount <= "000";
				nextbytecount <= bytecount + 1;
				nextstate <= D2;
      else
	  		nextbitcount <= bitcount + 1;
      end if;
      
    when D2 =>
      if( EN = '0' )
      then
				nextstate <= INIT;
      elsif( bitcount = "111" )
      then
				nextbitcount <= "000";
				nextbytecount <= bytecount + 1;
				if( bytecount = "1111100" )
				then
	  			nextstate <= FrameSync;
	  			nextbytecount <= "0000000";
				end if;
      else
				nextbitcount <= bitcount + 1;
      end if;
      
    end case;
    
  end process nextstate_logic;
  
  SYNC <= sync_int_f;
  
end tag_arch;

